Testing Your Agent
Overview
This guide covers integration testing for SMOCS agents, focusing on verifying agent behavior through logs, and Kafka UI.
Testing approach: Since agents run in containers and interact via Kafka, testing focuses on:
- Verifying correct startup and initialization
- Monitoring data flow through logs
- Validating database storage
- Confirming Kafka message publishing
Prerequisites
- Agent built and configured
- Docker Compose profiles set
.envfile configured- Kafka UI enabled (optional but helpful)
Step 1: Basic Startup Test
Start Agent
# Enable Kafka UI for testing
COMPOSE_PROFILES=gymnasium,threshold1,ui
docker compose up --build threshold-agent1 gymnasium-kafka-controller kafka-ui
Verify Container Running
docker compose ps
# Should show threshold-agent1 as "running" or "healthy"
Check Startup Logs
docker compose logs threshold-agent1 | head -50
Look for success indicators:
✓ Agent initialized
✓ Data Ingest Thread initialized
✓ ML Training Thread initialized
✓ ML Inference Thread initialized
✓ Connected to DB: agentdb
✓ Subscribed to topics: ['gymnasium-output']
Look for errors:
✗ Failed to connect to Kafka
✗ Database connection error
✗ Configuration error
✗ Module not found
Common Startup Issues
"Module not found" error:
# Check PYTHONPATH
docker exec threshold-agent1 echo $PYTHONPATH
# Should show: /app
# Verify smocs package exists
docker exec threshold-agent1 ls /app/smocs
Database connection failed:
# Check MySQL is running
docker exec threshold-agent1 mysqladmin ping -u root -p
# Check database exists
docker exec threshold-agent1 mysql -u root -p -e "SHOW DATABASES;"
Kafka connection failed:
# Verify Kafka is healthy
docker compose ps kafka-broker
# Test connectivity
docker exec threshold-agent1 nc -zv kafka-broker 9092
Step 2: Test Data Ingestion
Monitor Ingestion Logs
docker compose logs -f threshold-agent1 | grep "DataIngestThread"
Expected output:
DataIngestThread: Extracted 3 channels for processing
DataIngestThread: Stored sensor data: 3 channels
DataIngestThread: Extracted 3 channels for processing
DataIngestThread: Stored sensor data: 3 channels
Step 3: Test Training Thread
Monitor Training Logs
docker compose logs -f threshold-agent1 | grep "MLTrainingThread"
Before training:
MLTrainingThread: Database contains 150 samples (need 500)
MLTrainingThread: Not enough samples for training
During training:
MLTrainingThread: Found 600 samples
MLTrainingThread: Retrieved 600 samples for threshold calculation
MLTrainingThread: Calculated thresholds: {'state_0': 0.82, 'state_1': 0.79}
MLTrainingThread: Model evaluation complete
Verify Model Files Created
# List model files
docker exec threshold-agent1 ls -lh /app/models
# View threshold file
docker exec threshold-agent1 cat /app/models/current_thresholds.json
Expected content:
{
"thresholds": {
"state_0": 0.82,
"state_1": 0.79,
"state_2": 5.95
},
"metrics": {...},
"timestamp": 1704067200.0
}
Test Training Frequency
Monitor training cycles:
docker compose logs threshold-agent1 | grep "Training complete"
# Count training events
docker compose logs threshold-agent1 | grep "Training complete" | wc -l
Verify Alerts Published
Check Kafka UI:
- Open http://localhost:8080
- Navigate to "Topics"
- Select "threshold-alerts"
- View messages
Expected message format:
{
"timestamp": 1704067200.123,
"channels": {
"agent_id": "threshold-agent1",
"has_violation": true,
"violation_count": 1,
"state_0_value": 0.95,
"state_0_threshold": 0.82,
"state_0_exceeded_by": 0.13
}
}
Test Inference Without Training
Scenario: Inference thread starts before training completes
Expected behavior: Uses static thresholds from config
Verify:
# Check for static threshold usage
docker compose logs threshold-agent1 | grep "using static thresholds"
Step 5: Test End-to-End Flow
Full System Test
Setup:
- Clean database:
docker compose down -v - Start system:
docker compose up --build - Wait 5 minutes
Performance Check
Message processing rate:
# Count messages in 30 seconds
docker compose logs --since 30s threshold-agent1 | grep "Stored sensor data" | wc -l
Expected: Should match Gymnasium output rate
Check for lag:
# Look for timeout warnings
docker compose logs threshold-agent1 | grep -i timeout
Step 6: Test Error Handling
Invalid Message Format
Test without channels:
# Publish invalid message to Kafka
docker exec kafka-broker kafka-console-producer.sh \
--topic gymnasium-output \
--bootstrap-server localhost:9092 << EOF
{"timestamp": 1234567890}
EOF
Expected logs:
DataIngestThread: No channels in message
# Should continue processing, not crash
Database Unavailable
Test recovery:
# Stop MySQL inside container
docker exec threshold-agent1 service mysql stop
# Wait for error logs
docker compose logs -f threshold-agent1
# Restart MySQL
docker exec threshold-agent1 service mysql start
# Verify recovery
docker compose logs -f threshold-agent1 | grep "Connected to DB"
Kafka Unavailable
Test behavior:
# Stop Kafka
docker compose stop kafka-broker
# Check agent logs
docker compose logs threshold-agent1
# Restart Kafka
docker compose start kafka-broker
Expected: Agent should reconnect automatically
Step 7: Kafka UI Debugging
View Topics
Access: http://localhost:8080
Navigate: Topics → Select topic
Inspect Messages
Input messages (gymnasium-output):
- Click "Messages" tab
- Set "Live mode" to ON
- Observe incoming messages
- Verify format matches expected
Output messages (threshold-alerts):
- Check message count
- Verify only published on violations
- Inspect message content
Monitor Consumer Groups
Navigate: Consumers → Select group
Check metrics:
- Lag: Should be near 0
- Offset: Should be increasing
- Members: Should show 1 consumer
Troubleshooting Guide
Agent Not Processing Messages
Check:
- Kafka topic exists: Kafka UI
- Agent subscribed: Look for "Subscribed to topics" in logs
- Messages available: Check Kafka UI message count
- Consumer group active: Kafka UI → Consumers
Data Not Storing to Database
Check:
- Database accessible:
mysqladmin ping - Tables exist:
SHOW TABLES; - Permissions correct:
SHOW GRANTS; - Logs for SQL errors:
grep "DB Error"
Training Not Occurring
Check:
- Sufficient data: Query
agent_inferencescount - Thread running:
grep "MLTrainingThread" logs - Configuration correct: Verify
min_training_samples - No errors in training logic:
grep "Error.*training"
Inference Not Working
Check:
- Model/thresholds loaded:
ls /app/models - Input format correct: Log sample message
- Output topic created: Kafka UI
- Thread running:
grep "MLInferenceThread" logs
Clean state between tests:
docker compose down -v # Remove all data
docker compose up --build # Fresh start